home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / HENSA / MISC / SHELL.ARC / Shell / Sources / c / RedrawToSp < prev    next >
Encoding:
Text File  |  1994-11-23  |  4.8 KB  |  189 lines

  1. #include <string.h>
  2. #include <stdarg.h>
  3. #include <stdio.h>
  4. #include <math.h>
  5. #include <stdlib.h>
  6.  
  7. #include "DeskLib:ColourTran.h"
  8. #include "DeskLib:Sprite.h"
  9. #include "DeskLib:Screen.h"
  10. #include "DeskLib:SWI.h"
  11.  
  12. #include "Shell.Redraw2.h"
  13. #include "Shell.RedrawToSp.h"
  14. #include "Shell.Printf.h"
  15. #include "Shell.FindWind.h"
  16. #include "Shell.Extra.h"
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23. /*#define SWI_OS_SpriteOP 0x62*/
  24.  
  25.  
  26.  
  27.  
  28. BOOL Shell_SaveRectAsSprite( char *filename, Shell_rectblock *r, BOOL greyscale)
  29.     /* Most of this fn is taken up by finding the space for a sprite and     */
  30.     /* initialising it. The actual redrirect + redraw is fairly simple.    */
  31. {
  32. int            areasize, savesize, dummy;
  33. wimp_point        size;
  34. sprite_areainfo        *areainfo;
  35. sprite_outputstate    oldstate;
  36. void            *savebuffer;
  37. int            spritemode;
  38. FILE            *f;
  39.  
  40. f = fopen( filename, "w");
  41. if (!f) return FALSE;
  42.  
  43. Screen_CacheModeInfo();
  44. spritemode = (greyscale) ? 21 : screen_mode;
  45.  
  46. size.x = r->rect.max.x - r->rect.min.x;
  47. size.y = r->rect.max.y - r->rect.min.y;
  48.  
  49. areasize = sizeof( sprite_areainfo) +
  50.         Sprite_MemorySize(
  51.             size.x >> screen_eig.x,    /* X-size of sprite in pixels.    */
  52.             size.y >> screen_eig.y,    /* Y-size of sprite in pixels.    */
  53.             spritemode,
  54.             sprite_HASNOMASKPAL
  55.             );
  56.  
  57. if ( greyscale)    areasize += 2048;    /* extra space for the 256-entry palette.    */
  58.  
  59. areainfo = (sprite_areainfo *) malloc( areasize);
  60. if ( !areainfo)    {
  61.     Error_Report( 0, Error_PLACE "Shell can't malloc %i bytes for spritearea.", areasize);
  62.     return TRUE;
  63.     }
  64.  
  65. areainfo->areasize    = areasize;
  66. areainfo->numsprites    = 0;
  67. areainfo->firstoffset    = 16;
  68. areainfo->freeoffset    = 16;
  69. Sprite_InitArea( (sprite_area) areainfo);
  70.  
  71. if ( Sprite_Create(
  72.         (sprite_area) areainfo,
  73.         "Output",
  74.         0,    /* no palette    */
  75.         size.x >> screen_eig.x ,    /* x size of sprite in pixels.    */
  76.         size.y >> screen_eig.y,        /* y size of sprite in pixels.    */
  77.         spritemode
  78.         )
  79.     )
  80.     {
  81.     Error_Report( 0, Error_PLACE "Shell can't create sprite for saving");
  82.     free( areainfo);
  83.     return TRUE;
  84.     }
  85.  
  86. if (greyscale)    {
  87.     /* Add a 256-entry grey-scale palette to the created sprite, as per PRMs 1-832.    */
  88.         sprite_header    *spriteheader    = (sprite_header *) &areainfo[1];
  89.         int        *palette    = (int *) &spriteheader[1];
  90.         int        i;
  91.  
  92.     areainfo->freeoffset        += 2048;
  93.     spriteheader->offset_next    += 2048;
  94.     spriteheader->imageoffset    += 2048;
  95.     spriteheader->maskoffset    += 2048;
  96.  
  97.     for ( i=0; i<256; i++)    {    palette_entry    p;
  98.         p.value = 0;
  99.         p.data.red = p.data.green = p.data.blue = i;
  100.         palette[2*i] = palette[2*i+1] = p.value;    /* Why do we need 2 of each     */
  101.         }                        /* palette entry ???        */
  102.     }
  103.  
  104.  
  105. /* Find size of savebuffer.    */
  106. SWI( 3, 3, SWI_OS_SpriteOp, 256+62, areainfo, "Output", &dummy, &dummy, &savesize);
  107. savebuffer = calloc( 1, savesize);
  108.  
  109. if ( !savebuffer)    {
  110.     Error_Report(
  111.         0, Error_PLACE "Shell can't calloc %i bytes for savebuffer for sprite-redirection", savesize
  112.         );
  113.     free( areainfo);
  114.     return TRUE;
  115.     }
  116.  
  117. Sprite_Redirect( (sprite_area) areainfo, "Output", savebuffer, &oldstate);
  118.  
  119. /*
  120.     {
  121.     int in[8] = { 162, 163, -1};
  122.     int out[8];
  123.     SWI( 2, 0, 0x31, in, out);
  124.     Shell_WaitPrintf( "Text chr size inside sprite-redirection is (x,y) = (%i, %i)\n",
  125.         out[0], out[1]
  126.         );
  127.     }
  128. */
  129.  
  130. /* Now redraw the area    */
  131.     {
  132.     Shell_windblock        *wind    = Shell_FindWindBlock( r->window);
  133.     Shell_convertpoint    convert;
  134.  
  135.     /* Make all plotting (to sprite) be relative to r->rect by     */
  136.     /* giving the Shell redraw functions a doctored         */
  137.     /* Shell_convertpoint.                        */
  138.  
  139.     /* All Shell functions use 'convert' to plot to the screen, and    */
  140.     /* convert.x/y can be looked on as the screen coors of (0,0)     */
  141.     /* workarea coors. Hence if we pretend that (0,0) workarea is     */
  142.     /* at (-rect.min.x/y), rect.min.x/y will get mapped to 0,0     */
  143.     /* which will make all redrawing of rect fit the sprite     */
  144.     /* perfectly!                            */
  145.     convert.x = -r->rect.min.x;
  146.     convert.y = -r->rect.min.y;
  147.  
  148.  
  149.     if (greyscale)    {
  150.             /* Clear the sprite to white. This isn't necesary when     */
  151.             /* the sprite has no mask because colour 0 (which is     */
  152.             /* all pixels are because sprite is calloc-ed rather     */
  153.             /* than malloc-ed) is white when there is no mask.    */
  154.             /* With our grey-scale mask, colour 0 is in fact black.    */
  155.             /* Could possibly fill the palette in in reverse to     */
  156.             /* make colour 0 white, but that would be a bit of a     */
  157.             /* hack...                        */
  158.         palette_entry    p;
  159.         p.value        = 0;
  160.         p.data.red    = 255;
  161.         p.data.green    = 255;
  162.         p.data.blue    = 255;
  163.         ColourTrans_SetGCOL( p.value, 0 /* No ECFs */, 0 /* gcol action */);
  164.         Shell_RectangleFill( &r->rect, convert);
  165.         }
  166.  
  167.     Shell_WindRedraw2( &r->rect, convert, wind);
  168.     }
  169.  
  170.  
  171.  
  172. Sprite_UnRedirect( &oldstate);
  173.  
  174. /* Save the created sprite to whatever file handle we were given <Wimp$Scrap> for    */
  175. /* data transfers, and a normal filename if save was to the filer.            */
  176. fwrite( &areainfo->numsprites, sizeof( char), areasize, f);
  177.  
  178. free( areainfo);
  179.     /* I'm not sure whether one should tell the OS that this area    */
  180.     /* has been removed...                        */
  181.  
  182. free( savebuffer);
  183. fclose(f);
  184.  
  185. return TRUE;
  186. }
  187.  
  188.  
  189.